﻿using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.UIElements;
using XFABManager;

namespace XFGameFramework.HybridCLR
{
    public class SettingsWindow : EditorWindow
    {

        private Vector2 scrollView; 

        private Dictionary<string,ReorderableList> lists = new Dictionary<string, ReorderableList>();

        private GUIStyle style;
        private GUIContent content;

        [MenuItem("Window/XFKT/XFGameFramework/InstalledExtension/HybridCLR/Settings", false, 10)]
        static void Open()
        {
            GetWindow<SettingsWindow>().Show();
        }

        private void Awake()
        {
            titleContent = new GUIContent("Settings","设置热更程序集!");
        }

        private void OnGUI()
        { 

            GUILayout.Space(10);

            if (ProjectIsEmpty())
            {
                EditorGUILayout.HelpBox("未查询到资源模块,请添加资源模块后再设置热更程序集!", MessageType.Warning);
                GUILayout.Space(10);

                if (GUILayout.Button("添加资源模块"))
                {
                    XFAssetBundleManagerProjects window = GetWindow<XFAssetBundleManagerProjects>("XFABManager");
                    window.Show();
                }

            }
            else 
            {
                XFHybridCLRSettings.Instance.SyncProjects();

                scrollView = GUILayout.BeginScrollView(scrollView);

                for (int i = 0;i < XFHybridCLRSettings.Instance.settings.Count;i++)
                {
                    HybridCLRSettingInfo info = XFHybridCLRSettings.Instance.settings[i]; 
                    DrawInfo(info);
                }


                GUILayout.EndScrollView();
            }
             


        }

   
   
        private bool ProjectIsEmpty() {
            if (XFABProjectManager.Instance.Projects == null)
                return true;
            if (XFABProjectManager.Instance.Projects.Count == 0)
                return true;
            return false;
        }

      
        private void DrawInfo(HybridCLRSettingInfo info) 
        {

            EditorGUI.BeginChangeCheck();
            info.foldout = EditorGUILayout.Foldout( info.foldout, info.projectName);
            if (EditorGUI.EndChangeCheck()) 
                XFHybridCLRSettings.Instance.Save();
            
            GUILayout.BeginHorizontal();
            GUILayout.Space(10);
            GUILayout.BeginVertical();
            if (info.foldout) 
            {
                //EditorGUILayout.LabelField("ProjectName:", info.projectName);
                ReorderableList list = GetList(info); 
                list.DoLayoutList();
            }

            GUILayout.EndVertical();
            GUILayout.EndHorizontal();
        }


        private ReorderableList GetList(HybridCLRSettingInfo info) {

            if (lists.ContainsKey(info.projectName)) 
            {
                return lists[info.projectName];
            }

            ReorderableList reorderableList = new ReorderableList(info.infos, typeof(HotUpdateInfo),true,true,true,true);

            reorderableList.headerHeight = 20;
            reorderableList.onAddCallback += OnAddClick;
            reorderableList.onRemoveCallback += OnRemoveClick;

            reorderableList.drawHeaderCallback += OnDrawHeader;

            reorderableList.drawElementCallback += (Rect rect, int index, bool isActive, bool isFocused) => {
                OnDrawItem(info,rect,index,isActive,isFocused);
            };
            lists.Add(info.projectName,reorderableList);
             

            return reorderableList;
        }


        private void OnAddClick(ReorderableList list)
        {
            HotUpdateInfo info = new HotUpdateInfo(); 
            list.list.Add(info);
            XFHybridCLRSettings.Instance.Save();
        }
         
        private void OnRemoveClick(ReorderableList list) 
        {
            list.list.RemoveAt(list.index);
            XFHybridCLRSettings.Instance.Save();
        }

        private void OnDrawHeader(Rect rect) 
        {
            rect.Set(rect.x + 15, rect.y, rect.width / 3, rect.height);
            GUI.Label(rect, "程序集类型");
            rect.Set(rect.x + rect.width -10, rect.y, rect.width - 4, rect.height - 1);
            GUI.Label(rect, "程序集");

            if (style == null)
            {
                style = GUI.skin.label;
                style.richText = true;
            }

            if (content == null) {
                content = new GUIContent();
                content.text = "加载顺序(<color=yellow>值越小越先加载</color>)";
                content.tooltip = "值越小越先加载,被依赖的程序集应该要先加载,否则会报错! 比如程序集A依赖于B,则需要先加载B!";
            }

            rect.Set(rect.x + rect.width + 2, rect.y, rect.width - 4, rect.height - 1);
            GUI.Label(rect, content, style);
        }

        private void OnDrawItem(HybridCLRSettingInfo info, Rect rect, int index, bool isActive, bool isFocused) 
        {
            if (info == null)
                return;
            if (info.infos == null || info.infos.Count == 0)
                return;
            if (index < 0 || index >= info.infos.Count) 
                return;

            HotUpdateInfo update = info.infos[index];
            rect.Set(rect.x,rect.y,rect.width / 3 ,rect.height);
            EditorGUI.BeginChangeCheck();
            update.type = (HotUpdateType)EditorGUI.EnumPopup(rect, update.type);

            if (EditorGUI.EndChangeCheck()) 
            {
                XFHybridCLRSettings.Instance.Save();
            }

            rect.Set(rect.x + rect.width + 2, rect.y, rect.width - 4, rect.height - 1);

            switch (update.type)
            {
                case HotUpdateType.Assembly:
                    EditorGUI.BeginChangeCheck();
                    update.asset = (AssemblyDefinitionAsset)EditorGUI.ObjectField(rect,update.asset,typeof(AssemblyDefinitionAsset),false);
                    if (EditorGUI.EndChangeCheck()) 
                        XFHybridCLRSettings.Instance.Save();
                    break;
                case HotUpdateType.Dll:

                    EditorGUI.BeginChangeCheck();

                    update.dll =(DefaultAsset)EditorGUI.ObjectField(rect, update.dll, typeof(DefaultAsset), false);

                    if (EditorGUI.EndChangeCheck()) 
                    {
                        if (update.dll != null)
                        {
                            string path = AssetDatabase.GetAssetPath(update.dll);
                            if (!string.IsNullOrEmpty(path)) 
                            {
                                string extension = Path.GetExtension(path).ToLower();
                                if (extension != ".dll") 
                                {
                                    update.dll = null;

                                    this.ShowNotification(new GUIContent("请选择dll文件!"),2);
                                }
                            }
                        }

                        XFHybridCLRSettings.Instance.Save();
                    }

                

                    break; 
            }

            rect.Set(rect.x + rect.width + 2, rect.y, rect.width - 4, rect.height - 1);

            EditorGUI.BeginChangeCheck();

            update.loading_order = EditorGUI.IntField(rect, update.loading_order);

            if (EditorGUI.EndChangeCheck()) 
            {
                XFHybridCLRSettings.Instance.Save(); 
            }

        }


    }
}

